package bark.sihu;

import com.alibaba.fastjson2.JSON;
import jakarta.annotation.PostConstruct;
import org.hq.pojo.GroupsVideo;
import org.hq.pojo.HostWeb;
import org.hq.pojo.WebName;
import org.hq.service.sql.MysqlManageService;
import org.hq.upvideo.RedisKey;
import org.hq.upvideo.EupVideoTaskType;
import org.hq.sihu.task.ParseHtmlSiHuTask;
import org.hq.sihu.task.WebPojoTask;
import org.hq.util.MyHttpClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.*;

/**
 * 四虎网站更新数据服务
 */
@Component
public class UpdataService implements ItaskService {
    //redis 工具类
    private RedisTemplate<String, String> redis;
    //数据库管理对象
    private final MysqlManageService sqls;
    @Autowired
    public MyHttpClient myHttpClient;
    // 数据库单线程 线程池
    private ExecutorService sqlexec = Executors.newSingleThreadScheduledExecutor();//线程池
    // 任务最大数量
    private final int threadMax = 32;
    // 联网线程池 多线程执行
    private final ExecutorService exec;//线程池
    private final List<String> exeCount = Collections.synchronizedList(new ArrayList<>());
    public UpdataService(@Autowired RedisTemplate<String, String> redisString,
                         @Autowired MysqlManageService sqls) {
        this.sqls = sqls;
        this.redis = redisString;

        //初始化线程池
      //  this.exec = Executors.newFixedThreadPool(8);
        this.exec = Executors.newSingleThreadScheduledExecutor();

    }

    /**
     * 服务初始化
     */
    @PostConstruct
    private void init() {


    }


    /**
     * 视频更新服务
     */
    public void upVideo() {
        //1 获取所以网站对象
        List<WebName> lwn = sqls.getLisetWebName();

        for (WebName wn : lwn) {
            //获取最新网址
            HostWeb hw = sqls.getLimitHostWeb(wn);
            //获取子分组集合
            List<GroupsVideo> gvi = this.sqls.getListGroupsItme(wn);
            for (GroupsVideo gv : gvi) {
                //联网获取网页数量
                ParseHtmlSiHuTask h = new ParseHtmlSiHuTask();
                h.setEupVideoTaskType(EupVideoTaskType.PARSE_HTML_SIHU_PAGE_COUNT);
                h.setWebName(wn.getName());
                h.setWebId(wn.getId());
                h.setWebUrl(hw.getPath());

                h.setMenuId(gv.getPid());

                h.setMenuItemName(gv.getName());
                h.setMenuItemId(gv.getId());
                h.setMenuItemPath(gv.getPath());
                h.setTaskPath(gv.getPath());
                this.submit(h);
            }

        }


    }

    /**
     * 任务提交
     *
     * @param task 任务对象
     */
    @Override
    public synchronized final void submit(WebPojoTask task) {
        String key = null;
        //判断任务队列是否超出任务
        if (this.threadMax > this.exeCount.size()) {

            this.exec.submit(task);
            this.exeCount.add(String.valueOf(task.getEupVideoTaskType()));
            return;
        }
        //任务类型 用于保存任务数据到 redisk去
        switch (task.getEupVideoTaskType()) {
            case PARSE_HTML_SIHU_PAGE_COUNT:
                //四虎网站 解析 html 任务 保存
                key = String.valueOf(RedisKey.UP_VVIDE_TASK_SAVE_SIHU_KEY);
                break;

        }

        //  数据到 redisk 服务器
        this.redisSaveList(key, task);
    }



    /**
     * 任务完成处理剩余任务
     * 读取 redis 服务器 任务数据对象重新执行
     */
    @Override
    public synchronized void taskFinish() {
        // 任务类型判断
        String key = String.valueOf(RedisKey.UP_VVIDE_TASK_SAVE_SIHU_KEY);
        // 优先 1 解析 html 任务 保存
        long i = this.redis.opsForList().size(key);
        if (i > 0) {
            ParseHtmlSiHuTask parseHtmlSiHuTask = this.redisGetListLeftPop(key, ParseHtmlSiHuTask.class);
            if (parseHtmlSiHuTask != null) {
                this.exec.submit(parseHtmlSiHuTask);
                return;
            }
        }

        //重置任务数量
        if (this.exeCount.size() > 0) {
            this.exeCount.remove(0);
        }


    }

    /**
     * 任务出错处理
     *
     * @param task 任务线程对象数据
     */
    @Override
    public synchronized final void taskError(WebPojoTask task) {
        System.out.println("任务出错处理");
        System.out.println(task.getTaskPath());
        System.out.println(task.getEupVideoTaskType());
    }

    /**
     * redis list 集合保存
     *
     * @param key 建
     * @param obj 保存对象
     */
    public long redisSaveList(String key, Object obj) {
        // https://www.ad81c7.com/movie/oumei/
        ;//将 任务对象系列化为 json 数据
        String json = JSON.toJSONString(obj);
        return this.redis.opsForList().rightPush(key, json);
    }

    /**
     * 获取 redis 服务器 list 集合数据
     * 获取第一条数据
     *
     * @param key redis
     * @return 返回任务对象
     */
    private <T> T redisGetListLeftPop(String key, Class<T> claz) {
        if (this.redis.opsForList().size(key) > 0) {
            String json = this.redis.opsForList().leftPop(key);
            if (json == null) return null;//获取数据失败
            return JSON.parseObject(json, claz);
        }

        return null;
    }


}
